﻿Imports System
Imports System.ComponentModel.Design
Imports System.Drawing
Imports System.Globalization
Imports System.Windows.Forms
Imports System.Workflow.ComponentModel

Namespace System.Workflow.ComponentModel.Design
    Public Class SequenceDesignerAccessibleObject
        Inherits CompositeDesignerAccessibleObject
        ' Methods
        Public Sub New(ByVal activityDesigner As SequentialActivityDesigner)
            MyBase.New(activityDesigner)
        End Sub

        Public Overrides Function GetChild(ByVal index As Integer) As AccessibleObject
            Dim activityDesigner As SequentialActivityDesigner = [TryCast](MyBase.ActivityDesigner,SequentialActivityDesigner)
            If (Not activityDesigner.ActiveDesigner Is activityDesigner) Then
                Return MyBase.GetChild(index)
            End If
            If (((index >= 0) AndAlso (index < Me.GetChildCount)) AndAlso ((index Mod 2) = 0)) Then
                Return New SequentialConnectorAccessibleObject([TryCast](MyBase.ActivityDesigner,SequentialActivityDesigner), (index / 2))
            End If
            Return MyBase.GetChild((index / 2))
        End Function

        Public Overrides Function GetChildCount() As Integer
            Dim activityDesigner As SequentialActivityDesigner = [TryCast](MyBase.ActivityDesigner,SequentialActivityDesigner)
            If (Not activityDesigner.ActiveDesigner Is activityDesigner) Then
                Return MyBase.GetChildCount
            End If
            If (Not activityDesigner Is Nothing) Then
                Return ((activityDesigner.ContainedDesigners.Count + activityDesigner.ContainedDesigners.Count) + 1)
            End If
            Return -1
        End Function

        Public Overrides Function Navigate(ByVal navdir As AccessibleNavigation) As AccessibleObject
            If (((navdir = AccessibleNavigation.Up) OrElse (navdir = AccessibleNavigation.Previous)) OrElse ((navdir = AccessibleNavigation.Down) OrElse (navdir = AccessibleNavigation.Next))) Then
                Dim down As DesignerNavigationDirection = DesignerNavigationDirection.Down
                If ((navdir = AccessibleNavigation.Up) OrElse (navdir = AccessibleNavigation.Previous)) Then
                    down = DesignerNavigationDirection.Up
                Else
                    down = DesignerNavigationDirection.Down
                End If
                Dim parentDesigner As CompositeActivityDesigner = MyBase.ActivityDesigner.ParentDesigner
                If (Not parentDesigner Is Nothing) Then
                    Dim nextSelectableObject As Object = parentDesigner.GetNextSelectableObject(MyBase.ActivityDesigner.Activity, down)
                    If TypeOf nextSelectableObject Is ConnectorHitTestInfo Then
                        Return Me.GetChild(DirectCast(nextSelectableObject, ConnectorHitTestInfo).MapToIndex)
                    End If
                End If
            End If
            Return MyBase.Navigate(navdir)
        End Function


        ' Nested Types
        Private NotInheritable Class SequentialConnectorAccessibleObject
            Inherits AccessibleObject
            ' Methods
            Friend Sub New(ByVal activityDesigner As SequentialActivityDesigner, ByVal connectorIndex As Integer)
                If (activityDesigner Is Nothing) Then
                    Throw New ArgumentNullException("activityDesigner")
                End If
                Me.connectorHitInfo = New ConnectorHitTestInfo(activityDesigner, HitTestLocations.Designer, connectorIndex)
            End Sub

            Public Overrides Sub DoDefaultAction()
                Dim service As ISelectionService = [TryCast](Me.GetService(GetType(ISelectionService)),ISelectionService)
                If (Not service Is Nothing) Then
                    service.SetSelectedComponents(New Object() { Me.connectorHitInfo.SelectableObject }, SelectionTypes.Replace)
                Else
                    MyBase.DoDefaultAction
                End If
            End Sub

            Private Function GetService(ByVal serviceType As Type) As Object
                If ((Not Me.connectorHitInfo.AssociatedDesigner Is Nothing) AndAlso (Not Me.connectorHitInfo.AssociatedDesigner.Activity.Site Is Nothing)) Then
                    Return Me.connectorHitInfo.AssociatedDesigner.Activity.Site.GetService(serviceType)
                End If
                Return Nothing
            End Function

            Public Overrides Function Navigate(ByVal navdir As AccessibleNavigation) As AccessibleObject
                If ((navdir <> AccessibleNavigation.FirstChild) AndAlso (navdir <> AccessibleNavigation.LastChild)) Then
                    Dim down As DesignerNavigationDirection = DesignerNavigationDirection.Down
                    If (navdir = AccessibleNavigation.Left) Then
                        down = DesignerNavigationDirection.Left
                    ElseIf (navdir = AccessibleNavigation.Right) Then
                        down = DesignerNavigationDirection.Right
                    ElseIf ((navdir = AccessibleNavigation.Up) OrElse (navdir = AccessibleNavigation.Previous)) Then
                        down = DesignerNavigationDirection.Up
                    ElseIf ((navdir = AccessibleNavigation.Down) OrElse (navdir = AccessibleNavigation.Next)) Then
                        down = DesignerNavigationDirection.Down
                    End If
                    Dim nextSelectableObject As Object = DirectCast(Me.connectorHitInfo.AssociatedDesigner, CompositeActivityDesigner).GetNextSelectableObject(Me.connectorHitInfo, down)
                    If TypeOf nextSelectableObject Is ConnectorHitTestInfo Then
                        Dim info As ConnectorHitTestInfo = [TryCast](nextSelectableObject,ConnectorHitTestInfo)
                        Return New SequentialConnectorAccessibleObject([TryCast](info.AssociatedDesigner,SequentialActivityDesigner), info.MapToIndex)
                    End If
                    If TypeOf nextSelectableObject Is Activity Then
                        Dim designer As ActivityDesigner = ActivityDesigner.GetDesigner([TryCast](nextSelectableObject,Activity))
                        If (Not designer Is Nothing) Then
                            Return designer.AccessibilityObject
                        End If
                    End If
                End If
                Return MyBase.Navigate(navdir)
            End Function

            Public Overrides Sub [Select](ByVal flags As AccessibleSelection)
                Dim service As ISelectionService = [TryCast](Me.GetService(GetType(ISelectionService)),ISelectionService)
                If (Not service Is Nothing) Then
                    If (((flags And AccessibleSelection.TakeFocus) > AccessibleSelection.None) OrElse ((flags And AccessibleSelection.TakeSelection) > AccessibleSelection.None)) Then
                        service.SetSelectedComponents(New Object() { Me.connectorHitInfo.SelectableObject }, SelectionTypes.Replace)
                    ElseIf ((flags And AccessibleSelection.AddSelection) > AccessibleSelection.None) Then
                        service.SetSelectedComponents(New Object() { Me.connectorHitInfo.SelectableObject }, SelectionTypes.Add)
                    ElseIf ((flags And AccessibleSelection.RemoveSelection) > AccessibleSelection.None) Then
                        service.SetSelectedComponents(New Object() { Me.connectorHitInfo.SelectableObject }, SelectionTypes.Remove)
                    End If
                End If
            End Sub


            ' Properties
            Public Overrides ReadOnly Property Bounds As Rectangle
                Get
                    Return DirectCast(Me.connectorHitInfo.AssociatedDesigner, SequentialActivityDesigner).InternalRectangleToScreen(Me.connectorHitInfo.Bounds)
                End Get
            End Property

            Public Overrides ReadOnly Property DefaultAction As String
                Get
                    Return DR.GetString("AccessibleAction", New Object(0  - 1) {})
                End Get
            End Property

            Public Overrides ReadOnly Property Description As String
                Get
                    Return DR.GetString("ConnectorAccessibleDescription", New Object() { Me.connectorHitInfo.GetType.Name })
                End Get
            End Property

            Public Overrides ReadOnly Property Help As String
                Get
                    Return DR.GetString("ConnectorAccessibleHelp", New Object() { Me.connectorHitInfo.GetType.Name })
                End Get
            End Property

            Public Overrides Property Name As String
                Get
                    Return DR.GetString("ConnectorDesc", New Object() { Me.connectorHitInfo.MapToIndex.ToString(CultureInfo.InvariantCulture), Me.Parent.Name })
                End Get
                Set(ByVal value As String)
                End Set
            End Property

            Public Overrides ReadOnly Property Parent As AccessibleObject
                Get
                    Return Me.connectorHitInfo.AssociatedDesigner.AccessibilityObject
                End Get
            End Property

            Public Overrides ReadOnly Property Role As AccessibleRole
                Get
                    Return AccessibleRole.Diagram
                End Get
            End Property

            Public Overrides ReadOnly Property State As AccessibleStates
                Get
                    Dim multiSelectable As AccessibleStates = AccessibleStates.MultiSelectable
                    If Me.connectorHitInfo.AssociatedDesigner.IsLocked Then
                        multiSelectable = (multiSelectable Or AccessibleStates.ReadOnly)
                    End If
                    If Not Me.connectorHitInfo.AssociatedDesigner.IsVisible Then
                        multiSelectable = (multiSelectable Or AccessibleStates.Invisible)
                    End If
                    Dim service As ISelectionService = [TryCast](Me.GetService(GetType(ISelectionService)),ISelectionService)
                    If (Not service Is Nothing) Then
                        multiSelectable = (multiSelectable Or If(service.GetComponentSelected(Me.connectorHitInfo.SelectableObject), 2, &H200000))
                        multiSelectable = (multiSelectable Or If((service.PrimarySelection Is Me.connectorHitInfo.SelectableObject), 4, &H100000))
                    End If
                    Return multiSelectable
                End Get
            End Property


            ' Fields
            Private connectorHitInfo As ConnectorHitTestInfo
        End Class
    End Class
End Namespace

